#include "CAnswer.h"

_LIT(KGsmModuleName, "phonetsy.tsy");

CAnswer::CAnswer(MDisplayObserver& aDisplay):CActive(EPriorityStandard),iDisplay(aDisplay)
{
  	CActiveScheduler::Add( this );
}

CAnswer* CAnswer::NewL(MDisplayObserver& aDisplay)
{
	CAnswer * self = new (ELeave) CAnswer (aDisplay);
	CleanupStack::PushL( self );
	self->ConstructL(aDisplay);
	CleanupStack::Pop();
	return self;
}


void CAnswer::ConstructL(MDisplayObserver& aDisplay)
{	
	#ifdef __LOGGER
	  	iLog.Connect();
		iLog.CreateLog(_L("findme"),_L("CAnswer.txt"),EFileLoggingModeOverwrite);
	#endif	
	
	iConfig = CConfig::NewL(KConfigFile);
	if (iConfig->isValid() == EFalse) {
		iConfig->createConfigFile();
	}
	
	iConfig->get_phone_numberL(iPhoneNumber);
	#ifdef __LOGGER
  		iLog.WriteFormat(_L("Phone number loaded"));
  		iLog.WriteFormat(iPhoneNumber);
	#endif	
	iControlConnection = CControlConnection::NewL(*iConfig, aDisplay);
	
	StartL();
}

void CAnswer::StartL()
{
	#ifndef __EMULATOR
		TInt x = itelserver.Connect();
		User::LeaveIfError(x);
		TInt ret= itelserver.LoadPhoneModule(KGsmModuleName);
		User::LeaveIfError(ret);
		ret = itelserver.GetPhoneInfo(0, phoneInfo);
		User::LeaveIfError(ret);
		ret = iphone.Open(itelserver, phoneInfo.iName);
		User::LeaveIfError(ret);
		ret= iphone.Initialise();
		User::LeaveIfError(ret);
		WaitForACallL();
	#endif
	#ifdef __LOGGER
		iLog.Write(_L("Answer system initiated."));
	#endif	
}

void CAnswer::Stop()
{
	if (IsActive()) {
		Cancel();
	}
	#ifndef __EMULATOR
		iphone.Close();
		itelserver.UnloadPhoneModule(KGsmModuleName);
		itelserver.Close();
	#endif
}

void CAnswer::RunL()
{
	if (iStatus == KErrNone)
	{
		if (iState == EWaitingIncomingCall)
		{
			voiceline.GetInfo(lineInfo);
			callName.Copy(lineInfo.iNameOfCallForAnswering);
			ircall.OpenExistingCall(voiceline, callName);
			
			//Get the number phone of the incoming call			
			//RMobilePhone::TMobileAddress CallerID;
			RMobileCall::TMobileCallInfoV1 callInfo;
			RMobileCall::TMobileCallInfoV1Pckg callInfoPckg(callInfo);
			
			ircall.GetMobileCallInfo(callInfoPckg); 
			TBuf<32> callNum = callInfo.iRemoteParty.iRemoteNumber.iTelNumber; 
			
			#ifdef __LOGGER
				iLog.Write(_L("Call reveived from:"));
				iLog.Write(callNum);
			#endif
			
			if (iPhoneNumber.Right(PHONELENTOCOMPARE).CompareC(callNum.Right(PHONELENTOCOMPARE)) == 0) /* WARNING : it only compares the last 9 numbers */
			{
				#ifdef __LOGGER
					iLog.Write(_L("The phone number matches,"));				
					iLog.Write(_L("Starting connection."));
				#endif
				if (iControlConnection->isStarted()) {
					/* sleep a bit */
					RTimer timer;
					timer.CreateLocal();
					TRequestStatus tStatus;
					timer.After(tStatus, 4000000); /* wait 4 secs */
					User::WaitForRequest(tStatus);
					this->StopManually();
					ircall.HangUp();
				} else {
					ircall.HangUp();
					this->StartManually();
				}
			}
			else
			{
				#ifdef __LOGGER
					iLog.Write(_L("Phone number does not match."));	
				#endif
			} 
						
			//Reset system
			ircall.Close();
			voiceline.Close();
			//Start again		
			WaitForACallL();
		}
	}
	else
	{
		#ifdef __LOGGER
			iLog.WriteFormat(_L("error code=%d"),iStatus);	
		#endif
		Stop();
		StartL();
	}
}

void CAnswer::DoCancel()
{	
	#ifdef __LOGGER
		iLog.Write(_L("DoCancel called."));
	#endif
	RCall::TStatus iRcallStatus;
	voiceline.GetStatus(iRcallStatus);
	#ifdef __LOGGER
		iLog.WriteFormat(_L("voiceline.GetStatus=%d"),iStatus);
	#endif
	voiceline.NotifyIncomingCallCancel();
	ircall.Close();
	voiceline.Close();
	#ifdef __LOGGER
		iLog.Write(_L("The pendent call was cancelled."));
	#endif	
}

CAnswer::~CAnswer()
{
	Stop();		
	if (iControlConnection)
	{
		delete iControlConnection;
		iControlConnection = NULL;
	} 
	if (iConfig){
		delete iConfig;
		iConfig = NULL;
	}		
	#ifdef __LOGGER
		iLog.Write(_L("CAnswer destroyed."));
		iLog.CloseLog();
		iLog.Close();
	#endif
}

void CAnswer::WaitForACallL()
{	
	iphone.EnumerateLines(lineNum);
	if (lineNum >=4 )
	{
		TInt ret= iphone.GetLineInfo(0, lineVoiceInfo);
		User::LeaveIfError(ret);
		ret = voiceline.Open(iphone, lineVoiceInfo.iName);
		User::LeaveIfError(ret);
		TInt count=0;
		ret = voiceline.EnumerateCall(count);
		User::LeaveIfError(ret);
	}
	/*** open the Call for answering using RCall ***/
	voiceline.GetStatus(callStatus);
	voiceline.NotifyIncomingCall(iStatus, callName);
	iState = EWaitingIncomingCall;
	SetActive();
	#ifdef __LOGGER
		iLog.Write(_L("Waiting for a call."));
	#endif
}

CConfig* CAnswer::getConfig() {
	return iConfig;
}
void CAnswer::StartManually()
{
	#ifdef __LOGGER
		iLog.Write(_L("Starting connection."));	
	#endif
	#ifndef __EMULATOR
		iControlConnection->StartManually();
		TRAPD(err5, iControlConnection->getBtEngine()->ConnectL()); /* bluetooth will be switch on */
	#else
		iControlConnection->Start();
    #endif
}

void CAnswer::StopManually()
{
	#ifdef __LOGGER
		iLog.Write(_L("Stoping connection."));	
	#endif
	#ifndef __EMULATOR
		iControlConnection->StopManually();
		TRAPD(err5, iControlConnection->getBtEngine()->Disconnect());
	#else
		iControlConnection->Stop();
	#endif
}

CControlConnection* CAnswer::getControlConnection()
{
	return iControlConnection;
}

void CAnswer::setPhoneNumber(const TDesC& aPhoneNumber)
{
	if (aPhoneNumber.Length() > PHONENUMBERLENGTH || aPhoneNumber.Length() < PHONELENTOCOMPARE)
		return;
	iPhoneNumber.Copy(aPhoneNumber);
}